package caidan.data;

import caidan.MainApp;
import jinyilw.common.Operator;
import jinyilw.common.OperatorSets;
import jinyilw.common.TextTools;
import jinyilw.common.app.AppConfig;
import jinyilw.common.file.FileTools;
import jinyilw.swing.image.ThumbMaker;
import jinyilw.swing.visuals.window.HintWindow;

import java.awt.Image;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

public class FoodData implements Comparable<FoodData>
{
	final FoodCount foodCount = new FoodCount();
	final FoodProperty property = new FoodProperty();
	final FoodMaterial material = new FoodMaterial();
	private final CategoryData category;
	private String foodName, fileName;
	private File imageFile;
	private ThumbMaker thumbMaker;
	private boolean isInBreakfast;
	private boolean isInOther;
	private final OperatorSets<String> nameChangedOperaters = new OperatorSets<String>();

	public FoodData(CategoryData categoryData)
	{
		category = categoryData;
	}

	public FoodData(File file, String name, CategoryData categoryData)
	{
		imageFile = file;
		fileName = name;
		foodName = TextTools.getFileNameNoExt(name);
		category = categoryData;
	}

	public FoodData(File file, String fName, String cName,
			CategoryData categoryData)
	{
		imageFile = file;
		fileName = fName;
		foodName = cName;
		category = categoryData;
	}

	public static int getIndex(ArrayList<FoodData> list, String name)
	{
		if (list != null && name != null)
		{
			int i = 0, size = list.size();
			for (; i < size; i++)
				if (name.equals(list.get(i).foodName))
					return i;
		}
		return -1;
	}

	public static FoodData getData(ArrayList<FoodData> list, String name)
	{
		if (list != null && name != null)
		{
			int size = list.size();
			for (int i = 0; i < size; i++)
				if (name.equals(list.get(i).foodName))
					return list.get(i);
		}
		return null;
	}

	public static void isConflict(FoodData data1, FoodData data2)
	{

	}

	void setFoodData(String fName)
	{
		fileName = fName;
		foodName = TextTools.getFileNameNoExt(fName);
		File forder = category.breakfastFolder;
		if (!isInBreakfast)
			forder = category.otherFolder;
		imageFile = new File(forder, fName);
	}

	public void setFoodData(FoodData data)
	{
		foodName = data.foodName;
		property.setFoodProperty(data.property);
		material.setFoodMaterial(data.material);
	}

	public void clear()
	{
		property.clear();
		material.clear();
	}

	public void addNameChangedOperater(Operator<String> operator)
	{
		nameChangedOperaters.add(operator);
	}

	public void removeNameChangedOperater(Operator<String> operator)
	{
		nameChangedOperaters.remove(operator);
	}

	public void setFoodName(String name)
	{
		if (TextTools.isBlank(name))
		{
			HintWindow.showHint("菜单名称不能为空！");
			return;
		}
		if (!name.equals(foodName))
		{
			foodName = name;
			if (isInNone())
				return;
			String newFileName = name + "." + TextTools.getFileExt(fileName);
			if (isInBoth())
				new File(category.otherFolder, fileName)
						.renameTo(new File(category.otherFolder, newFileName));
			fileName = newFileName;
			thumbMaker.renameTo(foodName);
			imageFile = thumbMaker.getImageFile();
			nameChangedOperaters.operate(foodName);
		}
	}

	public void count(int d, int m)
	{
		foodCount.count(d, m);
	}

	public int getCount(int d, int m)
	{
		return foodCount.getCount(d, m);
	}

	//	public void totalCount()
	//	{
	//		caiCount.totalCount();
	//	}

	public void setInBoth()
	{
		isInBreakfast = true;
		isInOther = true;
	}

	public int getTotalCount()
	{
		return foodCount.getTotalCount();
	}

	public void setInBreakfast(boolean isInBreakfast)
	{
		this.isInBreakfast = isInBreakfast;
	}

	public void setInOther(boolean isInOther)
	{
		this.isInOther = isInOther;
	}

	public boolean isInBoth()
	{
		return isInBreakfast && isInOther;
	}

	public boolean isInNone()
	{
		return !isInBreakfast && !isInOther;
	}

	public boolean isInBreakfast()
	{
		return isInBreakfast;
	}

	public boolean isInOther()
	{
		return isInOther;
	}

	public boolean isMainFood()
	{
		return category.isMainFood;
	}

	public FoodCount getFoodCount()
	{
		return foodCount;
	}

	public Image getFoodImage()
	{
		if (thumbMaker == null)
			thumbMaker = new ThumbMaker(imageFile);
		return thumbMaker.getOriginalImage();
	}

	public Image getThumbnail()
	{
		if (thumbMaker == null)
			thumbMaker = new ThumbMaker(imageFile);
		return thumbMaker.getThumbnail();
	}

	public String getFileName()
	{
		return fileName;
	}

	public String getFoodName()
	{
		return foodName;
	}

	public FoodProperty getFoodProperty()
	{
		return property;
	}

	public FoodMaterial getFoodMaterial()
	{
		return material;
	}

	public String getImageNotFindMessege()
	{
		return "菜单图片未找到！请将 \"" + fileName + "\" 文件复制到 \"" + getCurrentPath()
				+ "\" 路径下";
	}

	public String getCurrentPath()
	{
		if (MainApp.isSelectBreakfast())
			return category.breakfastFolder.getAbsolutePath();
		return category.otherFolder.getAbsolutePath();
	}

	@Override
	public int compareTo(FoodData o)
	{
		return foodName.compareTo(o.foodName);
	}

	public void delete(boolean isSelectBreakfast)
	{
		if (!isInBoth())
			FileTools.copyFile(imageFile, new File(CategoryData.cDataFolder,
					"已删除" + File.separator + fileName));
		if (isSelectBreakfast)
		{
			if (isInOther)
			{
				File file = new File(category.otherFolder, fileName);
				FileTools.copyFile(imageFile, file);
				imageFile = file;
				thumbMaker.delete();
				thumbMaker.setFile(file);
			} else
				thumbMaker.delete();
			isInBreakfast = false;
		} else
		{
			if (isInBreakfast)
			{
				new File(category.otherFolder,
						".thumb" + File.separator + fileName).delete();
				new File(category.otherFolder, fileName).delete();
			} else
				thumbMaker.delete();
			isInOther = false;
		}
	}

	public void writeToFile(File file)
	{
		if (file == null)
			return;
		try (DataOutputStream dos = new DataOutputStream(
				new FileOutputStream(file)))
		{
			dos.writeInt(AppConfig.appVersion);
			property.writeData(dos);
			material.writeData(dos);
			dos.close();
		} catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	public void readFromFile(File file)
	{
		if (file == null)
			return;
		try (DataInputStream dis = new DataInputStream(
				new FileInputStream(file)))
		{
			int appVersion = dis.readInt();
			property.readData(dis, appVersion);
			material.readData(dis, appVersion);
			dis.close();
		} catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	void writeData(DataOutputStream dos) throws IOException
	{
		dos.writeBoolean(isInBreakfast);
		dos.writeBoolean(isInOther);
		dos.writeUTF(fileName);
		property.writeData(dos);
		material.writeData(dos);
	}

	void readData(DataInputStream dis, int appVersion) throws IOException
	{
		isInBreakfast = dis.readBoolean();
		isInOther = dis.readBoolean();
		setFoodData(dis.readUTF());
		property.readData(dis, appVersion);
		material.readData(dis, appVersion);
	}
}
